﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Reflection;
using CustomORM.DataAccess;
using CustomORM.Examples.Entities;
using CustomORM.Examples.Examples;
using CustomORM.Examples.Helpers;
using CustomORM.Mapping;

namespace CustomORM.Examples
{
    class Program
    {
        static void Main(string[] args)
        {
            //CormVsNhibernate.Run();

            MagicMapper.ScanForMappers(Assembly.GetExecutingAssembly());

            var settings = ConfigurationManager.ConnectionStrings["NorthwindConnectionString"];
            var ceDataAccess = new AdoDataAccess(settings.ConnectionString, settings.ProviderName);

            var customerRepository = new CustomerRepository(ceDataAccess);

            var fetchedCustomer = customerRepository.FetchCustomerByID("ALFKI");
            List<Customer> fetchAllCustomers = customerRepository.FetchAllCustomers();

            var results = MeasureExecTime.ExecTest(()=>RunCRUD(customerRepository));
            // 442
            //RunCRUD(customerRepository);
        }



        private static bool RunCRUD(CustomerRepository customerRepository)
        {
            // Creating Employee and Customer with 2 Orders served but Employee
            var employee = new Employee()
                               {
                                   FirstName = "FirstName",
                                   Address = "Address",
                                   City = "City",
                                   LastName = "LastName",
                                   Title = "SuperEmployee"
                               };

            var order1 = new Order() { OrderID = 9003, Employee = employee, OrderDate = DateTime.Now };
            var order2 = new Order() { OrderID = 9004, Employee = employee, OrderDate = DateTime.Now };

            var customer = new Customer()
                               {
                                   CustomerID = "TST",
                                   City = "City",
                                   CompanyName = "CompanyName",
                                   ContactName = "ContactName",
                                   ContactTitle = "SuperCustomer",
                                   Orders = new List<Order>() { order1, order2 }
                               };

            // Execute save
            var savedCustomer = customerRepository.SaveCustomer(customer);
            var customerId = savedCustomer.CustomerID;

            // Execute fetch
            var fetchedCustomer = customerRepository.FetchCustomerByID(customerId);

            // will thow exception if those are different
            VerifyCustomersAreTheSameFromInside(savedCustomer, fetchedCustomer);

            return true;
            // Execute delete
            customerRepository.DeleteCustomer(fetchedCustomer);

            // try to fetch the same customer after delete and get nothing 
            var fetchingDeletedCustomer = customerRepository.FetchCustomerByID(customerId);

            VerifyCustomersAreTheSameFromInside(fetchingDeletedCustomer, null);

            // was successful
            return true;
        }

        private static void VerifyCustomersAreTheSameFromInside(Customer customer1, Customer customer2)
        {
            // we are not verifying everything here, just basic things..

            if (ReferenceEquals(customer1, customer2))
            {
                return;
            }

            if (customer1.CustomerID != customer2.CustomerID)
            {
                throw new Exception("CustomerID are different");
            }

            if (customer1.Orders.Count != customer2.Orders.Count)
            {
                throw new Exception("Orders count is different");
            }

            for (int i = 0; i < customer1.Orders.Count; i++)
            {
                if (customer1.Orders[i].OrderID != customer2.Orders[i].OrderID)
                {
                    throw new Exception("Order ID is different");
                }

                if (customer1.Orders[i].Employee.EmployeeID != customer2.Orders[i].Employee.EmployeeID)
                {
                    throw new Exception("EmployeeID is different in order");
                }

                if (customer1.Orders[i].CustomerID != customer2.Orders[i].CustomerID)
                {
                    throw new Exception("CustomerID is different in orders");
                }
            }

        }
    }
}
